import { _decorator, Label, Node, ProgressBar, sp, Sprite, Tween, tween, UITransform, v3, Vec3 } from 'cc';
import { autoComp, autoNode } from '../../Basic/Manager/BaseManager';
import { MainModel_Ins } from './MainModel';
import { EventManager } from '../../Basic/Manager/EventManager';
import { GameEventType } from '../Config/GameEnum';
import { Role } from './Role';
import { WeaponItem } from './WeaponItem';
import { MathUtil } from '../../Util/MathUtil';
import { MultiPlatform } from '../../Basic/Model/Platform/MultiPlatform';

const { ccclass, property } = _decorator;
@ccclass('RolePlayer')
export class RolePlayer extends Role {
  @autoComp(sp.Skeleton)
  spine: sp.Skeleton;

  @autoComp(ProgressBar)
  bar_hp: ProgressBar;
  @autoComp(Sprite)
  bar: Sprite;
  @autoComp(Label)
  lab_bar: Label;
  @autoNode()
  weaponNode: Node;

  curState: string = '';
  protected onLoad(): void {
    this.spine.setCompleteListener(this.onSpineComplete.bind(this));
  }

  dataChanged(): void {
    this.refreshHp();
    this.playAni('Idle5');
  }

  refreshHp() {
    this.lab_bar.string = `${this.data.hp}/${this.data.hpMax}`;
    Tween.stopAllByTarget(this.bar_hp);
    let rate = this.data.hp / this.data.hpMax;
    rate = rate <= 0 ? 0 : rate;
    rate = rate >= 1 ? 1 : rate;
    this.bar_hp.node.active = true;
    tween(this.bar_hp)
      .to(0.2, { progress: rate })
      .delay(0.2)
      .call(() => {
        this.bar_hp.node.active = false;
      })
      .start();
  }

  playAni(state: string) {
    if (this.curState === state) return;
    this.curState = state;
    let loop = false;
    switch (this.curState) {
      case 'Idle5':
      case 'Walk':
        loop = true;
        break;
    }
    this.spine.setAnimation(0, this.curState, loop);
  }

  onSpineComplete(t: sp.spine.TrackEntry) {
    switch (t.animation.name) {
      case 'Attack':
      case 'Attack3':
        this.playAni('Idle');
        break;
    }
  }

  protected update(dt: number): void {
    if (this.IsDeah) return;
    // if (this.movePath.length > 0) {
    //   this.playAni('Walk');
    //   // 移动
    //   const lPos = this.node.getPosition().clone();
    //   const movePos = this.movePath[0];
    //   const targetPos = MainModel_Ins.basePanel.getPosVec3(movePos);
    //   const moveDir = new Vec3(targetPos.x - lPos.x, targetPos.y - lPos.y);
    //   const length = moveDir.length();
    //   if (length <= 10) {
    //     // this.gridPos = this.movePath.shift();
    //     // if (this.movePath.length <= 0) this.playAni('Idle');
    //   }
    //   const dir = moveDir.normalize();
    //   this.node.setPosition(lPos.add(v3(dir.x * 100 * dt, dir.y * 100 * dt)));
    // } else if (this.atkTarget !== null) {
    //   this.atkCount += dt;
    //   if (this.atkCount >= this.atkSpace) {
    //     this.atkCount = 0;
    //     this.attack();
    //   }
    // }
    if (!this.moveLock) {
      const lPos = this.node.getPosition().clone();
      const moveDir = this.moveDir.clone();
      const moveS = this.moveSpace * dt * this.moveSpeed;
      this.spine.node.setScale(moveDir.x >= 0 ? 1 : -1, 1);
      MainModel_Ins.basePanel.moveMap(moveDir.multiplyScalar(-moveS));
      // this.node.setPosition(lPos.add(moveDir.multiplyScalar(moveS)));
    }

    if (this.weaponNode.children.length > 0) this.updateWeaponAngle(dt);
  }

  private moveLock: boolean = true;
  private moveDir: Vec3 = null;
  private moveSpeed: number = 1;
  private moveSpace: number = 200;
  move(dir: Vec3, speed: number) {
    this.moveDir = dir;
    this.moveSpeed = speed;
    this.moveLock = false;
    this.playAni('Walk');
  }

  stopMove() {
    this.moveLock = true;
    this.playAni('Idle5');
  }

  hirt(value: number) {
    this.data.hp -= value;
    this.data.hp = this.data.hp <= 0 ? 0 : this.data.hp;
    this.refreshHp();
    if (this.IsDeah) this.die();
  }

  // private atkTarget: Role = null;
  // private atkSpace: number = 1;
  // private atkCount: number = 0;
  // /** 检测攻击对象 */
  // checkAtkTarget(targetArr: Role[]) {
  //   let target = null;
  //   let minDis = 9999;
  //   const enemyPos = this.node.getPosition().clone();
  //   targetArr.forEach((tower) => {
  //     const towerPos = tower.node.getPosition().clone();
  //     const dis = new Vec3(towerPos.x - enemyPos.x, towerPos.y - enemyPos.y);
  //     if (dis.length() <= minDis) {
  //       minDis = dis.length();
  //       target = tower;
  //     }
  //   });
  //   this.atkTarget = target;
  //   // if (this.atkTarget !== null && this.movePath.length <= 0) {
  //   //   // this.setMovePath(MainModel_Ins.basePanel.getMovePath(this.gridPos, this.atkTarget.gridPos));
  //   // }
  // }

  // attack() {
  //   const atkTarget = this.atkTarget;
  //   const atkValue = this.data.atk;
  //   // this.playAni(Math.random() > 0.5 ? 'Attack' : 'Attack3');
  //   if (atkTarget.IsDeah || atkTarget.node.parent === null) this.atkTarget = null;
  //   else atkTarget.hirt(atkValue);
  //   // EventManager.Ins().emit(GameEventType.MAIN_CREATE_BUTTLE, bPos, ePos, () => {
  //   //   if (atkTarget.IsDeah) return;
  //   //   else atkTarget.hirt(atkValue);
  //   // });
  // }

  updateWeaponPos() {
    if (this.weaponNode.children.length <= 0) return;
    const spaceAngle = 360 / this.weaponNode.children.length;
    const rate = this.weaponNode.children.length / 6 <= 1 ? 1 : this.weaponNode.children.length / 6;
    const radius = 100 * (rate >= 2 ? 2 : rate);
    this.weaponNode.children.forEach((weapon, i) => {
      const angle = spaceAngle * i;
      const x = radius * Math.cos((angle * Math.PI) / 180);
      const y = radius * Math.sin((angle * Math.PI) / 180);
      weapon.setPosition(x, y);
      weapon.angle = angle - 90;
    });
  }

  rotateAngle: number = 270;
  rotateSpeed: number = 1;

  updateWeaponAngle(dt: number) {
    this.weaponNode.angle += this.rotateAngle * this.rotateSpeed * dt;
    if (this.weaponNode.angle >= 360) this.weaponNode.angle -= 360;
  }

  addWeapon(weapon: WeaponItem) {
    this.weaponNode.addChild(weapon.node);
    this.updateWeaponPos();
  }

  checkWeapon(enemyArr, treeArr) {
    this.weaponNode.children.forEach((weapon) => {
      const weaponScript = weapon.getComponent(WeaponItem);
      weaponScript.checkWoodHit(treeArr);
      weaponScript.checkEnemyHit(enemyArr);
    });
  }

  checkWoodDis(woodArr: Node[]) {
    const lPos = this.node.getWorldPosition();
    const coinParent = MainModel_Ins.basePanel.coin;
    const coinTrans = coinParent.getComponent(UITransform);
    coinTrans.convertToNodeSpaceAR(lPos, lPos);
    woodArr.forEach((wood) => {
      const woodPos = wood.getPosition().clone();
      const space = new Vec3(woodPos.x - lPos.x, woodPos.y - lPos.y, 0);
      if (space.length() <= 50) {
        MainModel_Ins.basePanel.recoverItem(wood);
      }
    });
  }

  checkDropWeaponDis(weaponArr: WeaponItem[]) {
    const lPos = this.node.getWorldPosition();
    const mapParent = MainModel_Ins.basePanel.mapNode;
    const mapTrans = mapParent.getComponent(UITransform);
    mapTrans.convertToNodeSpaceAR(lPos, lPos);
    weaponArr.forEach((weapon) => {
      const woodPos = weapon.node.getPosition().clone();
      const space = new Vec3(woodPos.x - lPos.x, woodPos.y - lPos.y, 0);
      if (space.length() <= 50) {
        if (MainModel_Ins.basePanel.weaponArr.indexOf(weapon)) MainModel_Ins.basePanel.weaponArr.splice(MainModel_Ins.basePanel.weaponArr.indexOf(weapon), 1);
        this.addWeapon(weapon);
      }
    });
  }

  die() {
    EventManager.Ins().emit(GameEventType.MAIN_RECOVER, this.node);
    console.log('player die');
    MultiPlatform.Ins().platformUnit.notifyMiniProgramPlayableStatus();

    // MainModel_Ins.basePanel.enemyCount--;
    // MainModel_Ins.basePanel.enemyCount = MainModel_Ins.basePanel.enemyCount <= 0 ? 0 : MainModel_Ins.basePanel.enemyCount;
  }
}
